<!-- 下拉框 todo
  1.需要给定按钮id
  2.主轴覆盖检测
-->
<template>
  <a :btn-id="`dropview_${btnId}`" ondragstart="return false" ref="dropwrap" href="javascript:void(0)"
     class="dropwrap" :style="viewStyle" :class="autoClose?'':'noAutoClose'">
    <div v-show="show" class="view" @click="autoClose?close($event):null">
      <slot name="default"></slot>
    </div>
  </a>
</template>

<script>
  export default {
    name: "Dropdown",
    props: {
      // 弹窗方向
      direction: {
        type: String,
        default: 'down'
      },
      btnId: {
        type: String,
        default: ''
      },
      autoClose: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        show: false,
        top: 0,
        left: 0,
      };
    },

    mounted() {
      this.btn = document.querySelector(`#${this.btnId}`);
      this.btn.addEventListener('click', event => {
        this.activeView();
      });
    },
    methods: {
      // 关闭
      close() {
        this.show = false;
        this.$refs.dropwrap.blur();
      },
      activeView(directionNum = this.directionNum, exeCont = 0) {
        ++exeCont;
        this.top = 0;
        this.left = 0;
        this.show = true;
        this.$nextTick(_ => {
          this.$refs.dropwrap.focus();
          this.$nextTick(_ => {
            const dropBtn = this.btn.getBoundingClientRect();
            const view = this.$refs.dropwrap.getBoundingClientRect();
            const r = this.tryShow(directionNum, dropBtn, view);
            if (!r && exeCont < 4) {
              if (exeCont === 1) {
                this.activeView(directionNum, exeCont);
              } else if (exeCont === 2) {
                this.activeView(-directionNum, exeCont);
              } else if (exeCont === 3) {
                this.activeView(directionNum, exeCont);
              }
            } else {

            }
          });
        });
      },
      /** 尝试显示弹框
       * @param {number} typeNum - 方向编号：1上 -1下 2左 -2 右
       * @return {boolean} - 是否符合尺寸
       * */
      tryShow(typeNum, {left, top, width, height}, {left: Vleft, top: Vtop, width: Vwidth, height: Vheight}) {
        let r = false;
        // 按方向计算主轴位置，并做溢出判断
        switch (typeNum) {
          case -1:
            this.top = top - Vtop + height;
            r = (this.top + Vtop + Vheight) <= this.winHeight;
            break;
          case 1:
            this.top = top - Vtop - Vheight;
            r = (this.top + Vtop) >= 0;
            break;
          case -2:
            this.left = left - Vleft + width;
            r = (this.left + Vleft + Vwidth) <= this.winWidth;
            break;
          case 2:
            this.left = left - Vleft - Vwidth;
            r = (this.left + Vleft) >= 0;
            break;
          default:
            r = true;
        }
        // 计算交叉轴位置
        if (Math.abs(this.directionNum) === 1) {
          this.left = left - Vleft;
        } else {
          this.top = top - Vtop;
        }
        return r;
      }
    },

    computed: {
      viewStyle() {
        return {
          top: `${this.top}px`,
          left: `${this.left}px`
        };
      },
      // 方向编号
      directionNum() {
        return {
          up: 1,
          down: -1,
          left: 2,
          right: -2,
        }[this.direction];
      },

      // 系统信息
      winWidth() {
        return this.$store.getters.clientWidth;
      },
      winHeight() {
        return this.$store.getters.clientHeight;
      },
    },
    watch: {}
  }
</script>

<style scoped>
  .dropwrap {
    color: inherit;
    position: absolute;
    z-index: var(--menu_zindex);
    background: white;
  }

  .dropwrap:focus {
    display: block;
  }

  .view {
    display: none;
  }

  .dropwrap:focus .view {
    display: block;
  }

  .noAutoClose:hover .view {
    display: block;
  }
</style>
